package tr.gov.tubitak.uekae.esya.api.cades.example.sign;

import junit.framework.TestCase;
import tr.gov.tubitak.uekae.esya.api.asn.x509.ECertificate;
import tr.gov.tubitak.uekae.esya.api.cades.example.testconstans.TestConstants;
import tr.gov.tubitak.uekae.esya.api.cades.example.validation.ValidationUtil;
import tr.gov.tubitak.uekae.esya.api.cmssignature.ISignable;
import tr.gov.tubitak.uekae.esya.api.cmssignature.SignableFile;
import tr.gov.tubitak.uekae.esya.api.cmssignature.attribute.EParameters;
import tr.gov.tubitak.uekae.esya.api.cmssignature.signature.BaseSignedData;
import tr.gov.tubitak.uekae.esya.api.cmssignature.signature.ESignatureType;
import tr.gov.tubitak.uekae.esya.api.cmssignature.validation.SignedDataValidationResult;
import tr.gov.tubitak.uekae.esya.api.cmssignature.validation.SignedData_Status;
import tr.gov.tubitak.uekae.esya.api.common.crypto.BaseSigner;
import tr.gov.tubitak.uekae.esya.api.smartcard.example.SmartCardManager;
import tr.gov.tubitak.uekae.esya.asn.util.AsnIO;

import java.io.File;
import java.util.HashMap;

public class ExternalContentSign extends TestCase
{
	private String mp3File = "D:\\mp3\\yabancı\\dido\\a.mp3";
	private String movieFile = "D:\\share\\film\\Life\\Life S01E01 Challenges of Life.mkv";
	
	
	/**
	 * creates BES type signature with normal size external content and validate it.
	 * @throws Exception
	 */
	public void testSignSmallFile() throws Exception
	{
		BaseSignedData bs = new BaseSignedData();
		
		File file = new File(mp3File);
		ISignable externalContent = new SignableFile(file,32 * 1024);
		
		//create parameters necessary for signature creation
		HashMap<String, Object> params = new HashMap<String, Object>();
		
		
		//necessary for certificate validation.By default,certificate validation is done.But if the user 
		//does not want certificate validation,he can add P_VALIDATE_CERTIFICATE_BEFORE_SIGNING parameter with its value set to false
		params.put(EParameters.P_CERT_VALIDATION_POLICY, TestConstants.getPolicy());
		
		//By default, QC statement is checked,and signature wont be created if it is not a qualified certificate
		boolean checkQCStatement = TestConstants.getCheckQCStatement();
		bs.addContent(externalContent,false);
		
		
		//Get qualified or non-qualified certificate.
		ECertificate cert = SmartCardManager.getInstance().getSignatureCertificate(checkQCStatement, !checkQCStatement);
		BaseSigner signer = SmartCardManager.getInstance().getSigner(TestConstants.getPIN(), cert);
		
		
		//add signer
		//Since the specified attributes are mandatory for bes,null is given as parameter for optional attributes
		bs.addSigner(ESignatureType.TYPE_BES, cert, signer, null, params);
		
		SmartCardManager.getInstance().logout();
		
		byte [] signature = bs.getEncoded();
		
		//write the contentinfo to file
		AsnIO.dosyayaz(signature, TestConstants.getDirectory() + "testdata/SmallExternalContent.p7s");
		
		SignedDataValidationResult sdvr = ValidationUtil.validate(signature, externalContent);
		
		assertEquals(SignedData_Status.ALL_VALID, sdvr.getSDStatus());
	}
	
	
	
	/**
	 * creates BES type signature with huge external content and validate it. Use external signature for huge files.
	 * @throws Exception
	 */
	public void testSignHugeFile() throws Exception
	{
		BaseSignedData bs = new BaseSignedData();
		
		File file = new File(movieFile);
		ISignable externalContent = new SignableFile(file,32 * 1024);
		
		//create parameters necessary for signature creation
		HashMap<String, Object> params = new HashMap<String, Object>();
		
		//necessary for certificate validation.By default,certificate validation is done.But if the user 
		//does not want certificate validation,he can add P_VALIDATE_CERTIFICATE_BEFORE_SIGNING parameter with its value set to false
		params.put(EParameters.P_CERT_VALIDATION_POLICY, TestConstants.getPolicy());
		
		//By default, QC statement is checked,and signature wont be created if it is not a qualified certificate
		boolean checkQCStatement = TestConstants.getCheckQCStatement();
		params.put(EParameters.P_VALIDATE_CERTIFICATE_BEFORE_SIGNING, false);
		
		bs.addContent(externalContent,false);
		
		//Get qualified or non-qualified certificate.
		ECertificate cert = SmartCardManager.getInstance().getSignatureCertificate(checkQCStatement, !checkQCStatement);
		BaseSigner signer = SmartCardManager.getInstance().getSigner(TestConstants.getPIN(), cert);
		
		//add signer
		//Since the specified attributes are mandatory for bes,null is given as parameter for optional attributes
		bs.addSigner(ESignatureType.TYPE_BES, cert, signer, null, params);
		
		SmartCardManager.getInstance().logout();
		
		byte [] signature = bs.getEncoded();
		
		//write the contentinfo to file
		AsnIO.dosyayaz(signature, TestConstants.getDirectory() + "testdata/HugeExternalContent.p7s");
		
//		SignedDataValidationResult sdvr = ValidationUtil.validate(signature, externalContent);
//		
//		assertEquals(SignedData_Status.ALL_VALID, sdvr.getSDStatus());
	}
	
	
	/**
	 * 
	 */
	public void testAddingParalelSignature() throws Exception
	{
		byte [] signature = AsnIO.dosyadanOKU(TestConstants.getDirectory() + "testdata/SmallExternalContent.p7s");
		
		File file = new File(mp3File);
		ISignable externalContent = new SignableFile(file,2048);
		
		BaseSignedData bsd = new BaseSignedData(signature);
		HashMap<String, Object> params = new HashMap<String, Object>();
		
		//necessary for certificate validation.By default,certificate validation is done.But if the user 
		//does not want certificate validation,he can add P_VALIDATE_CERTIFICATE_BEFORE_SIGNING parameter with its value set to false
		params.put(EParameters.P_CERT_VALIDATION_POLICY, TestConstants.getPolicy());
				
		//By default, QC statement is checked,and signature wont be created if it is not a qualified certificate
		boolean checkQCStatement = TestConstants.getCheckQCStatement();
		params.put(EParameters.P_VALIDATE_CERTIFICATE_BEFORE_SIGNING, false);
		params.put(EParameters.P_EXTERNAL_CONTENT, externalContent);
		
		//Get qualified or non-qualified certificate.
		ECertificate cert = SmartCardManager.getInstance().getSignatureCertificate(checkQCStatement, !checkQCStatement);
		BaseSigner signer = SmartCardManager.getInstance().getSigner(TestConstants.getPIN(), cert);
				
		//add signer
		//Since the specified attributes are mandatory for bes,null is given as parameter for optional attributes
		bsd.addSigner(ESignatureType.TYPE_BES, cert, signer, null, params);
				
		SmartCardManager.getInstance().logout();
				
		byte [] signatureWithTwoSigner = bsd.getEncoded();
		
		AsnIO.dosyayaz(signatureWithTwoSigner, TestConstants.getDirectory() + "testdata/twoSigner.p7s");
		
		SignedDataValidationResult sdvr = ValidationUtil.validate(signature, externalContent);
		assertEquals(SignedData_Status.ALL_VALID, sdvr.getSDStatus());
	}
	
	
}
